home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / comm / ums / ums109_1.lha / Tools / UMSMM.LHA / UMSMM / UMSMM.c < prev    next >
C/C++ Source or Header  |  1994-06-08  |  21KB  |  785 lines

  1. /* 
  2.  * UMSMailMon - UMS Mail Monitor 
  3.  *
  4.  * Monitors an UMS messagebase for unread mail.
  5.  *
  6.  * Based on Sabot V1.7 by Scott Ellis
  7.  *
  8.  *************************************************************************
  9.  *
  10.  *   Copyright (C) 1994 Thomas Schwarz
  11.  *                      <blacky@bmagic.mayn.sub.de>
  12.  *                      <Thomas_Schwarz@wue.maus.de>
  13.  *
  14.  *   This program is free software; you can redistribute it and/or modify
  15.  *   it under the terms of the GNU General Public License as published by
  16.  *   the Free Software Foundation; either version 2 of the License, or
  17.  *   any later version.
  18.  *
  19.  *   This program is distributed in the hope that it will be useful,
  20.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.  *   GNU General Public License for more details.
  23.  *
  24.  *   You should have received a copy of the GNU General Public License
  25.  *   along with this program; if not, write to the Free Software
  26.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27.  *
  28.  *************************************************************************
  29.  *
  30.  * History:
  31.  *
  32.  * V1.0 + Initial release
  33.  * V1.1 + Lost some memory when started from workbench
  34.  *      + If the number of new mails changed, the new number was not displayed
  35.  *      + Several cleanups
  36.  *      + Two new icons (mt*.info) contributed by Ralf Garbade. Thanks Ralf!
  37.  */
  38.  
  39. #include "UMSMM.h"
  40.  
  41. #define BIGSTRING 255
  42.  
  43. #define VERSION "1.1"
  44.  
  45. STRPTR VersionID = "\0$VER: UMSMailMon "VERSION" (" __COMMODORE_DATE__ ")";
  46.  
  47. enum args
  48.         {
  49.         NAME,
  50.         PASSWORD,
  51.         SERVER,
  52.         MAIL,
  53.         NOMAIL,
  54.         NOTIFY,
  55.         TIMER,
  56.         XPOS,
  57.         YPOS,
  58.         CLICKCOMMAND,
  59.         CLICKSTACK,
  60.         MAILCOMMAND,
  61.         MAILSTACK,
  62.         DROPCOMMAND,
  63.         DROPSTACK
  64.         };
  65.  
  66. enum active_args
  67.         {
  68.         LOGIN,
  69.         NONE,
  70.         NEW
  71.         };
  72.  
  73. struct WBStartup *WBStart = NULL;
  74.  
  75. UMSUserAccount MyUMSAccount = 0;
  76.  
  77. extern struct Library *UMSBase;
  78. extern struct Library *IconBase;
  79. extern struct Library *WorkbenchBase;
  80.  
  81. struct MsgPort *MyPort = NULL;
  82. struct AppIcon *MyAppIcon = NULL;
  83. struct DiskObject *MyImage = NULL;
  84. struct NotifyRequest *MyNoteReq = NULL;
  85. ULONG MyNoteSigNum = -1L;
  86. struct timerequest *TimeReq = NULL;
  87. ULONG MyTimerSig = 0;
  88.  
  89. STRPTR Name = NULL, Password = NULL, Server = NULL;
  90. STRPTR HaveMail = NULL;
  91. STRPTR NoMail = NULL;
  92. STRPTR Watch = NULL;
  93. STRPTR ClickComName = NULL;
  94. STRPTR MailComName = NULL;
  95. STRPTR DropComName = NULL;
  96. ULONG ClickComStack = 4096;
  97. ULONG MailComStack = 4096;
  98. ULONG DropComStack = 4096;
  99. ULONG XPos = 0;
  100. ULONG YPos = 0;
  101. ULONG Timer = 0;
  102.  
  103. LONG UnreadMails = 0;
  104. LONG PrevUnreadMails = 0;
  105.  
  106. USHORT Active = LOGIN;
  107.  
  108. VOID wbmain(struct WBStartup *);
  109. ULONG main(ULONG, STRPTR *);
  110. BOOL AddIcon(struct MsgPort *, struct DiskObject *);
  111. VOID KillIcon(VOID);
  112. BOOL GetImage(STRPTR);
  113. VOID KillImage(VOID);
  114. VOID ChangeIcon(VOID);
  115. VOID DoInfo(VOID);
  116. VOID Compare(VOID);
  117. BOOL Parse(LONG, STRPTR *);
  118. VOID DoCommand(STRPTR, ULONG);
  119. BOOL MakeVars(VOID);
  120. VOID FreeVars(VOID);
  121. VOID BeginNotify(VOID);
  122. BOOL OpenTimer(VOID);
  123. VOID CloseTimer(VOID);
  124.  
  125. VOID chkabort(VOID)
  126.    {
  127.    }
  128.  
  129. /// "wbmain"
  130.  
  131. VOID wbmain(struct WBStartup *wbs)
  132.    {
  133.    WBStart = wbs;
  134.  
  135.    main(0, NULL);
  136.    }
  137.  
  138. ///
  139.  
  140. /// "main"
  141.  
  142. ULONG main(ULONG argc, STRPTR *argv)
  143.    {
  144.    struct AppMessage *appmsg = NULL;
  145.    BOOL going = TRUE;
  146.    ULONG mysig = 0;
  147.    ULONG myportsig = 0;
  148.    ULONG waitsigs = 0;
  149.    LONG count = 0;
  150.  
  151.    if (!MakeVars())
  152.       {
  153.       FreeVars();
  154.  
  155.       return 20;
  156.       }
  157.  
  158.    if (!Parse(argc, argv))
  159.       {
  160.       FreeVars();
  161.       
  162.       return 20;
  163.       }
  164.  
  165.    if(Timer)
  166.       {
  167.       if(!OpenTimer())
  168.          {
  169.          CloseTimer();
  170.       
  171.          FreeVars();
  172.  
  173.          return 20;
  174.          }
  175.       }
  176.  
  177.    if (MyPort = CreatePort(NULL, 0))
  178.       {
  179.       myportsig = (1L << MyPort->mp_SigBit);
  180.  
  181.       if (GetImage(NoMail))
  182.          {
  183.          if (AddIcon(MyPort, MyImage))
  184.             {
  185.             /* log into UMS system */
  186.             
  187.             if (MyUMSAccount = UMSRLogin(Server, Name, Password))
  188.                {
  189.                DoInfo();
  190.                if (UnreadMails) /* Show appropriate icon on startup */
  191.                   Active = NEW;
  192.                else
  193.                   Active = NONE;
  194.                ChangeIcon();
  195.  
  196.                if(strlen(Watch))
  197.                   BeginNotify();
  198.  
  199.                waitsigs = myportsig | SIGBREAKF_CTRL_C;
  200.                if(Timer)
  201.                   waitsigs |= MyTimerSig;
  202.                if(MyNoteReq)
  203.                   waitsigs |= (1L << MyNoteSigNum);
  204.  
  205.                while (going)
  206.                   {
  207.                   mysig = Wait(waitsigs);
  208.  
  209.                   if (mysig & SIGBREAKF_CTRL_C)
  210.                      going = FALSE;
  211.  
  212.                   if (Timer && (mysig & MyTimerSig))
  213.                      {
  214.                      WaitIO((struct IORequest *)TimeReq);
  215.  
  216.                      DoInfo();
  217.  
  218.                      Compare();
  219.                      
  220.                      TimeReq->tr_time.tv_secs  = Timer;
  221.                      TimeReq->tr_time.tv_micro = 0;
  222.                      SendIO((struct IORequest *)TimeReq);
  223.                      }
  224.  
  225.                   if (MyNoteReq && (mysig & (1L << MyNoteSigNum)))
  226.                      {
  227.                      DoInfo();
  228.  
  229.                      Compare();
  230.                      }
  231.  
  232.                   if (mysig & myportsig)
  233.                      {
  234.                      while(appmsg = (struct AppMessage *)GetMsg(MyPort))
  235.                         {
  236.                         if (appmsg->am_NumArgs == 0)
  237.                            {
  238.                            if (*ClickComName)
  239.                               {
  240.                               if(!strcmp(ClickComName, "QUIT"))
  241.                                  going = FALSE;
  242.                               else
  243.                                  DoCommand(ClickComName, ClickComStack);
  244.                               }
  245.                            }
  246.                         else if (appmsg->am_NumArgs > 0)
  247.                            {
  248.                            if (*DropComName)
  249.                               {
  250.                               TEXT dropname[BIGSTRING], droptemp[2 * BIGSTRING];
  251.  
  252.                               count = appmsg->am_NumArgs;
  253.  
  254.                               while (count)
  255.                                  {
  256.                                  --count;
  257.  
  258.                                  if (NameFromLock(appmsg->am_ArgList[count].wa_Lock, dropname, BIGSTRING))
  259.                                     {
  260.                                     if (AddPart(dropname, appmsg->am_ArgList[count].wa_Name, BIGSTRING))
  261.                                        {
  262.                                        sprintf(droptemp, "%s %s", DropComName, dropname);
  263.                                        DoCommand(droptemp, DropComStack);
  264.                                        }
  265.                                     }
  266.                                  
  267.                                  strcpy(droptemp, "");
  268.                                  strcpy(dropname, "");
  269.                                  }
  270.                               }
  271.                            }
  272.                         
  273.                         ReplyMsg((struct Message *)appmsg);
  274.                         }
  275.                      }
  276.                   }
  277.                
  278.                if(MyNoteReq)
  279.                   {
  280.                   EndNotify(MyNoteReq);
  281.                   FreeSignal(MyNoteSigNum);
  282.                   FreeVec(MyNoteReq);
  283.                   }
  284.  
  285.                UMSLogout(MyUMSAccount);
  286.                }
  287.  
  288.             KillIcon();
  289.             }
  290.  
  291.          KillImage();
  292.          }
  293.    
  294.       while(appmsg = (struct AppMessage *)GetMsg(MyPort))
  295.          ReplyMsg((struct Message *)appmsg);
  296.  
  297.       DeletePort(MyPort);
  298.       }
  299.  
  300.    if(Timer)
  301.       {
  302.       if(!CheckIO((struct IORequest *)TimeReq))
  303.          AbortIO((struct IORequest *)TimeReq);
  304.       WaitIO((struct IORequest *)TimeReq);
  305.       CloseTimer();
  306.       }
  307.  
  308.    FreeVars();
  309.  
  310.    return 0;
  311.    }
  312.  
  313. ///
  314.  
  315. /// "AddIcon"
  316.  
  317. BOOL AddIcon(struct MsgPort *port, struct DiskObject *image)
  318.    {
  319.    TEXT iconname[32];
  320.  
  321.    if (Active == LOGIN)
  322.       strcpy(iconname, "Logging in...");
  323.    else
  324.       {
  325.       if(UnreadMails == 1)
  326.          sprintf(iconname, "%d New Mail!", UnreadMails);
  327.       else if(UnreadMails)
  328.          sprintf(iconname, "%d New Mails!", UnreadMails);
  329.       else
  330.          strcpy(iconname, "No Mail Today");
  331.       }
  332.  
  333.    if (MyAppIcon = AddAppIconA(0, 0, iconname, port, NULL, image, NULL))
  334.       return TRUE;
  335.  
  336.    return FALSE;
  337.    }
  338.  
  339. ///
  340.  
  341. /// "KillIcon"
  342.  
  343. VOID KillIcon(VOID)
  344.    {
  345.    RemoveAppIcon(MyAppIcon);
  346.    }
  347.  
  348. ///
  349.  
  350. /// "GetImage"
  351.  
  352. BOOL GetImage(STRPTR name)
  353.    {
  354.    if (MyImage = GetDiskObject(name))
  355.       {
  356.       MyImage->do_Type = NULL;
  357.       MyImage->do_CurrentX = XPos;
  358.       MyImage->do_CurrentY = YPos;
  359.  
  360.       return TRUE;
  361.       }
  362.  
  363.    return FALSE;
  364.    }
  365.  
  366. ///
  367.  
  368. /// "KillImage"
  369.  
  370. VOID KillImage(VOID)
  371.    {
  372.    if (MyImage)
  373.       FreeDiskObject(MyImage);
  374.    }
  375.  
  376. ///
  377.  
  378. /// "ChangeIcon"
  379.  
  380. VOID ChangeIcon(VOID)
  381.    {
  382.    KillIcon();
  383.    KillImage();
  384.  
  385.    switch (Active)
  386.       {
  387.       case NEW:
  388.          GetImage(HaveMail);
  389.          break;
  390.  
  391.       case NONE:
  392.       case LOGIN:
  393.          GetImage(NoMail);
  394.          break;
  395.       }
  396.  
  397.    AddIcon(MyPort, MyImage);
  398.    }
  399.  
  400. ///
  401.  
  402. /// "DoInfo"
  403.  
  404. VOID DoInfo(VOID)
  405.    {
  406.    UMSMsgNum result = 0;
  407.  
  408.    UMSSelectTags(MyUMSAccount, UMSTAG_SelWriteLocal, TRUE,
  409.                                UMSTAG_SelUnset,      (1L<<0)|(1L<<1)|(1L<<2),
  410.                                TAG_DONE);
  411.  
  412.    /******************************************************************
  413.    
  414.    1. For all messages with
  415.  
  416.        (GlobalFlags & (ReadAccess|PostPoned|Old)) == ViewAccess
  417.  
  418.       set the local flag bit 0.
  419.  
  420.       These are all NEW messages, which can be read by the user.
  421.     
  422.     ******************************************************************/
  423.  
  424.    UMSSelectTags(MyUMSAccount, UMSTAG_SelMask,       UMSUSTATF_ReadAccess | UMSUSTATF_PostPoned | UMSUSTATF_Old,
  425.                                UMSTAG_SelMatch,      UMSUSTATF_ReadAccess,
  426.                                UMSTAG_SelWriteLocal, TRUE,
  427.                                UMSTAG_SelSet,        (1L<<0),
  428.                                TAG_DONE);
  429.    
  430.    /*******************************************************************
  431.    
  432.    2. For all messages with
  433.  
  434.       Group == NULL (i.e. mail)
  435.  
  436.       set the local flag bit 1.
  437.  
  438.       These are all mail messages.
  439.     
  440.     *******************************************************************/
  441.  
  442.    UMSSelectTags(MyUMSAccount, UMSTAG_WGroup,        NULL,
  443.                                UMSTAG_SelWriteLocal, TRUE,
  444.                                UMSTAG_SelSet,        (1L<<1),
  445.                                UMSTAG_SelQuick,      TRUE,
  446.                                TAG_DONE);
  447.    
  448.    /*******************************************************************
  449.    
  450.    3. For all messages with
  451.  
  452.       (LocalFlags & (Bit 0 and Bit 1)) == (Bit 0 and Bit 1)
  453.  
  454.       set the local flag bit 2.
  455.  
  456.       This operation builds the intersection set of operation 1 and 2,
  457.       thus setting the local flag bit 2 in all new mails, which are
  458.       addressed to the user.
  459.  
  460.     ******************************************************************/
  461.  
  462.    result = UMSSelectTags(MyUMSAccount, UMSTAG_SelReadLocal,  TRUE,
  463.                                         UMSTAG_SelMask,       (1L<<0) | (1L<<1),
  464.                                         UMSTAG_SelMatch,      (1L<<0) | (1L<<1),
  465.                                         UMSTAG_SelWriteLocal, TRUE,
  466.                                         UMSTAG_SelSet,        (1L<<2),
  467.                                         TAG_DONE);
  468.  
  469.    UnreadMails = result;
  470.    }
  471.  
  472. ///
  473.  
  474. /// "Compare"
  475.  
  476. VOID Compare(VOID)
  477.    {
  478.    if (UnreadMails)
  479.       {
  480.       if (Active != NEW || PrevUnreadMails != UnreadMails)
  481.          {
  482.          Active = NEW;
  483.  
  484.          ChangeIcon();
  485.          }
  486.  
  487.       if (UnreadMails > PrevUnreadMails)
  488.          if (*MailComName)
  489.             DoCommand(MailComName, MailComStack);
  490.       }
  491.    else
  492.       {
  493.       if (Active != NONE)
  494.          {
  495.          Active = NONE;
  496.  
  497.          ChangeIcon();
  498.          }
  499.       }
  500.  
  501.    PrevUnreadMails = UnreadMails;
  502.    }
  503.  
  504. ///
  505.  
  506. /// "Parse"
  507.  
  508. STRPTR HelpTxt = "\nUMSMailMon V"VERSION" ©1994 Thomas Schwarz\n" \
  509.                  "                based on Sabot V1.7 by Scott Ellis\n\n" \
  510.                  " NAME/A            UMS username.\n" \
  511.                  " PASSWORD/A        UMS password.\n" \
  512.                  " SERVER/K          UMS servername.\n" \
  513.                  " MA=MAIL/K         Name of icon to be shown to indicate that you have some\n" \
  514.                  "                   new mail (without \".info\" extension). Def: \"Filled\"\n" \
  515.                  " NM=NOMAIL/K       Name of icon to be shown to indicate that you have *no*\n" \
  516.                  "                   new mail (without \".info\" extension). Def: \"Empty\"\n" \
  517.                  " NO=NOTIFY/K       Name of a file or directory to be monitored. Everytime\n" \
  518.                  "                   this changes, a check for mail is done. Def: No checks\n" \
  519.                  " TI=TIMER/K/N      Number of seconds between mail checks. Def: No checks\n" \
  520.                  " XPOS/K/N          Horizontal icon position in pixels. Def: Free floating\n" \
  521.                  " YPOS/K/N          Vertical icon position in pixels. Def: Free floating\n" \
  522.                  " CC=CLICKCOMMAND/K Command to be executed when AppIcon is double-clicked.\n" \
  523.                  " CS=CLICKSTACK/K/N Stacksize which CLICKCOMMAND is to be run with. If\n" \
  524.                  "                   CLICKCOMMAND was omitted, CLICKSTACK has no effect.\n" \
  525.                  " MC=MAILCOMMAND/K  Command to be executed when new mail arrives.\n" \
  526.                  " MS=MAILSTACK/K/N  Works according to CLICKSTACK, but for MAILCOMMAND.\n" \
  527.                  " DC=DROPCOMMAND/K  Command to be executed when icons are dropped on the\n" \
  528.                  "                   AppIcon. This command is executed once for each icon\n" \
  529.                  "                   dropped with the name of the icon appended to it.\n" \
  530.                  " DS=DROPSTACK/K/N  Works according to CLICKSTACK, but for DROPCOMMAND.\n\n";
  531.  
  532. BOOL Parse(LONG argc, STRPTR *argv)
  533.    {
  534.    struct RDArgs *rda;
  535.    LONG argumentarray[16] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
  536.    STRPTR *toolarrayindex, toolstringindex, template;
  537.    struct DiskObject *diskobject;
  538.  
  539.    rda = AllocDosObjectTags(DOS_RDARGS, TAG_DONE);
  540.    rda->RDA_ExtHelp = HelpTxt;
  541.  
  542.    if (argc == 0)
  543.       {
  544.       CurrentDir(WBStart->sm_ArgList->wa_Lock);
  545.  
  546.       if (diskobject = GetDiskObject(WBStart->sm_ArgList->wa_Name))
  547.          {
  548.          for (toolarrayindex = diskobject->do_ToolTypes; *toolarrayindex; toolarrayindex++)
  549.             rda->RDA_Source.CS_Length += strlen(*toolarrayindex) + 1;
  550.          
  551.          rda->RDA_Source.CS_Buffer = AllocVec(rda->RDA_Source.CS_Length + 1, MEMF_CLEAR);
  552.  
  553.          toolstringindex = rda->RDA_Source.CS_Buffer;
  554.          for (toolarrayindex = diskobject->do_ToolTypes; *toolarrayindex; toolarrayindex++)
  555.             toolstringindex = stpcpy(stpcpy(toolstringindex, *toolarrayindex), " ");
  556.  
  557.          *(toolstringindex-1) = '\n';
  558.  
  559.          FreeDiskObject(diskobject);
  560.          }
  561.  
  562.       template = "NAME/A,PASSWORD/A,SERVER/K,MA=MAIL/K,NM=NOMAIL/K,NO=NOTIFY/K,TI=TIMER/K/N,XPOS/K/N,YPOS/K/N,CC=CLICKCOMMAND/K,CS=CLICKSTACK/K/N,MC=MAILCOMMAND/K,MS=MAILSTACK/K/N,DC=DROPCOMMAND/K,DS=DROPSTACK/K/N,THROWAWAY/M";
  563.       }
  564.    else
  565.       template = "NAME/A,PASSWORD/A,SERVER/K,MA=MAIL/K,NM=NOMAIL/K,NO=NOTIFY/K,TI=TIMER/K/N,XPOS/K/N,YPOS/K/N,CC=CLICKCOMMAND/K,CS=CLICKSTACK/K/N,MC=MAILCOMMAND/K,MS=MAILSTACK/K/N,DC=DROPCOMMAND/K,DS=DROPSTACK/K/N";
  566.  
  567.    if (rda = ReadArgs(template, argumentarray, rda))
  568.       {
  569.       strcpy(Name, (STRPTR)argumentarray[NAME]);
  570.       strcpy(Password, (STRPTR)argumentarray[PASSWORD]);
  571.  
  572.       if (argumentarray[SERVER])
  573.          strcpy(Server, (STRPTR)argumentarray[SERVER]);
  574.  
  575.       if (argumentarray[NOTIFY])
  576.          strcpy(Watch, (STRPTR)argumentarray[NOTIFY]);
  577.  
  578.       if (argumentarray[MAIL])
  579.          strcpy(HaveMail, (STRPTR)argumentarray[MAIL]);
  580.       else
  581.          strcpy(HaveMail, "Filled");
  582.  
  583.       if (argumentarray[NOMAIL])
  584.          strcpy(NoMail, (STRPTR)argumentarray[NOMAIL]);
  585.       else
  586.          strcpy(NoMail, "Empty");
  587.  
  588.       if (argumentarray[TIMER])
  589.          Timer = *(ULONG *)argumentarray[TIMER];
  590.  
  591.       if (argumentarray[XPOS])
  592.          XPos = *(ULONG *)argumentarray[XPOS];
  593.       else
  594.          XPos = NO_ICON_POSITION;
  595.  
  596.       if (argumentarray[YPOS])
  597.          YPos = *(ULONG *)argumentarray[YPOS];
  598.       else
  599.          YPos = NO_ICON_POSITION;
  600.  
  601.       if (argumentarray[CLICKCOMMAND])
  602.          strcpy(ClickComName, (STRPTR)argumentarray[CLICKCOMMAND]);
  603.       else
  604.          strcpy(ClickComName, "QUIT");
  605.  
  606.       if (argumentarray[CLICKSTACK])
  607.          ClickComStack = *(ULONG *)argumentarray[CLICKSTACK];
  608.  
  609.       if (argumentarray[MAILCOMMAND])
  610.          strcpy(MailComName, (STRPTR)argumentarray[MAILCOMMAND]);
  611.  
  612.       if (argumentarray[MAILSTACK])
  613.          MailComStack = *(ULONG *)argumentarray[MAILSTACK];
  614.  
  615.       if (argumentarray[DROPCOMMAND])
  616.          strcpy(DropComName, (STRPTR)argumentarray[DROPCOMMAND]);
  617.  
  618.       if (argumentarray[DROPSTACK])
  619.          DropComStack = *(ULONG *)argumentarray[DROPSTACK];
  620.       }
  621.    else
  622.       {
  623.       PrintFault(IoErr(), NULL);
  624.       
  625.       return FALSE;
  626.       }
  627.  
  628.    FreeArgs(rda);
  629.    FreeVec(rda->RDA_Source.CS_Buffer);
  630.    FreeDosObject(DOS_RDARGS, rda);
  631.  
  632.    return TRUE;
  633.    }
  634.  
  635. ///
  636.  
  637. /// "DoCommand"
  638.  
  639. VOID DoCommand(STRPTR command, ULONG stack)
  640.    {
  641.    BPTR ofh, ifh;
  642.  
  643.    if(!*command)
  644.       return;
  645.  
  646.    if (ofh = Open("NIL:", MODE_READWRITE))
  647.       {
  648.       if (ifh = Open("NIL:", MODE_READWRITE))
  649.          {
  650.          if (SystemTags(command,
  651.                         SYS_Input, ifh,
  652.                         SYS_Output, ofh,
  653.                         SYS_UserShell, DOSTRUE,
  654.                         SYS_Asynch, DOSTRUE,
  655.                         NP_StackSize, stack,
  656.                         NP_CopyVars, DOSTRUE,
  657.                         NP_Cli, DOSTRUE,
  658.                         TAG_END) != -1)
  659.             return;
  660.  
  661.          Close(ifh);
  662.          }
  663.  
  664.       Close(ofh);
  665.       }
  666.    }
  667.  
  668. ///
  669.  
  670. /// "MakeVars"
  671.  
  672. BOOL MakeVars(VOID)
  673.    {
  674.    if (HaveMail = AllocVec(9 * BIGSTRING, MEMF_CLEAR))
  675.       {
  676.       NoMail = HaveMail + BIGSTRING;
  677.       Watch = NoMail + BIGSTRING;
  678.       ClickComName = Watch + BIGSTRING;
  679.       MailComName = ClickComName + BIGSTRING;
  680.       DropComName = MailComName + BIGSTRING;
  681.       Name = DropComName + BIGSTRING;
  682.       Password = Name + BIGSTRING;
  683.       Server = Password + BIGSTRING;
  684.  
  685.       return TRUE;
  686.       }
  687.    
  688.    return FALSE;
  689.    }
  690.  
  691. ///
  692.  
  693. /// "FreeVars"
  694.  
  695. VOID FreeVars(VOID)
  696.    {
  697.    if (HaveMail)
  698.       FreeVec(HaveMail);
  699.    }
  700.  
  701. ///
  702.  
  703. /// "BeginNotify"
  704.  
  705. VOID BeginNotify(VOID)
  706.    {
  707.    if (MyNoteReq = AllocVec(sizeof(struct NotifyRequest), MEMF_CLEAR))
  708.       {
  709.       if ((MyNoteSigNum = AllocSignal(-1L)) != -1L)
  710.          {
  711.          MyNoteReq->nr_Name = Watch;
  712.          MyNoteReq->nr_Flags = NRF_SEND_SIGNAL;
  713.          MyNoteReq->nr_stuff.nr_Signal.nr_Task = (struct Task *)FindTask(NULL);
  714.          MyNoteReq->nr_stuff.nr_Signal.nr_SignalNum = MyNoteSigNum;
  715.  
  716.          if ((StartNotify(MyNoteReq)) == DOSTRUE)
  717.             return;
  718.  
  719.          FreeSignal(MyNoteSigNum);
  720.          MyNoteSigNum = -1L;
  721.          }
  722.  
  723.       FreeVec(MyNoteReq);
  724.       MyNoteReq = NULL;
  725.       }
  726.    }
  727.  
  728. ///
  729.  
  730. /// "OpenTimer"
  731.  
  732. BOOL OpenTimer(VOID)
  733.    {
  734.    struct MsgPort *timer_port = NULL;
  735.    
  736.    if (timer_port = CreatePort(NULL, 0))
  737.       {
  738.       if (TimeReq = (struct timerequest *)CreateExtIO(timer_port, sizeof(struct timerequest)))
  739.          {
  740.          if (!OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)TimeReq, 0))
  741.             {
  742.             TimeReq->tr_node.io_Command = TR_ADDREQUEST;
  743.             TimeReq->tr_node.io_Flags = 0;
  744.             TimeReq->tr_node.io_Error = 0;
  745.  
  746.             MyTimerSig = (1L << TimeReq->tr_node.io_Message.mn_ReplyPort->mp_SigBit);
  747.  
  748.             TimeReq->tr_time.tv_secs  = Timer;
  749.             TimeReq->tr_time.tv_micro = 0;
  750.  
  751.             SendIO((struct IORequest *)TimeReq);
  752.  
  753.             return TRUE;
  754.             }
  755.  
  756.          TimeReq->tr_node.io_Device = 0;
  757.          }
  758.       
  759.       DeletePort(timer_port);
  760.       }
  761.    
  762.    return FALSE;
  763.    }
  764.  
  765. ///
  766.  
  767. /// "CloseTimer"
  768.  
  769. VOID CloseTimer(VOID)
  770.    {
  771.    if (TimeReq)
  772.       {
  773.       if (TimeReq->tr_node.io_Device)
  774.          CloseDevice((struct IORequest *)TimeReq);
  775.       if (TimeReq->tr_node.io_Message.mn_ReplyPort)
  776.          DeletePort(TimeReq->tr_node.io_Message.mn_ReplyPort);
  777.       DeleteExtIO((struct IORequest *)TimeReq);
  778.  
  779.       MyTimerSig = 0;
  780.       TimeReq = NULL;
  781.       }
  782.    }
  783.  
  784. ///
  785.